package reflect;

import java.io.FileInputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Scanner;
/**
 * java反射机制
 *
 * 类对象(Class)，该类的每一个实例用于表示JVM加载的一个类的信息。反射操作的第一步就是获取要操作的类的
 * 类对象
 * JVM在使用一个类时，会读取该类的字节码文件，然后实例化一个Class对象记录加载的这个类的信息，因此在
 * JVM内部每个被加载的类都有且只有一个Class的实例与之关联。这个Class的实例称为类对象。
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
            获取一个类的类对象主要方式:
            1:类名.class
              例如:
              Class cls = String.class

              Class cls = int.class
              基本类型获取类对象方式只有上述这一种

            2:对象.getClass()
              例如:
              String s = "hello";
              Class cls = s.getClass();

            3:Class.forName("类的完全限定名")   类的完全限定名：包名.类名
              例如:
              Class cls = Class.forName("java.lang.String");
            4:ClassLoader.loadClass("类的完全限定名")
              例如:
              Class cls = ClassLoader.getSystemClassLoader().loadClass("java.lang.String");
         */

        //获取String的类对象，用于了解String的相关信息
//        Class cls = String.class;
//        Class cls = ArrayList.class;
//        Class cls = FileInputStream.class;

//        Class cls = Class.forName("java.lang.String");
//        Class cls = Class.forName("java.util.ArrayList");
//        Class cls = Class.forName("java.io.FileInputStream");

        Scanner scanner = new Scanner(System.in);
        System.out.println("输入一个类名");
        String classname = scanner.nextLine();
        Class cls = Class.forName(classname);
        //获取当前类对象表示的类的完全限定名
        String name = cls.getName();
        System.out.println(name);
        //仅获取类名字
        name = cls.getSimpleName();
        System.out.println(name);
        /*
           Packge和Class一样都是反射对象
           只不过Class的每个实例表示的是一个类的全部信息，而Package仅仅便是该类的包信息
         */
        Package pack = cls.getPackage();//当前cls表示的是String类，获取的是String的包信息
        System.out.println(pack.getName());//输出包名
        /*
           Meth也是反射对象之一
           他的每一个实例用于表示一个方法的信息
         */

        Method[] methods = cls.getMethods();
        System.out.println("共"+methods.length+"个方法");
        for(Method m:methods){
            System.out.println(m.getName());
        }

    }
}
